﻿using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Loader;

namespace 日志的使用.自定义的内容
{
    //注册普通服务，通过程序集
    public static class RegisterService
    {       
        /// <summary>
        /// 程序集依赖注入
        /// </summary>
        /// <param name="builder">服务</param>
        /// <param name="assemblyName">程序集名称，不要带DLL</param>
        /// <param name="serviceLifetime">依赖注入的类型，可空</param>
        public static void AddServices(this WebApplicationBuilder builder, string assemblyName, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
        {
            //var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(m => m.FullName.Contains("1.0.0.0")); //获取当前的程序集
            if (string.IsNullOrEmpty(assemblyName)) throw new ArgumentNullException(nameof(RegisterService));
            Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(assemblyName));
            if (null==assembly) throw new DllNotFoundException(nameof(RegisterService));
            var listType = assembly.GetTypes().Where(m => m.IsClass && !m.IsAbstract && !m.IsGenericType).ToList(); //获取程序集下的所有类，但不包含抽象类和泛型类
            foreach (var type in listType)
            {
                Type[] arrType= type.GetInterfaces();
                if (null == arrType || arrType.Length < 1) continue;
                foreach (var interfaceType in arrType)
                {
                    switch (serviceLifetime)
                    {
                        case ServiceLifetime.Singleton:
                            builder.Services.TryAddSingleton(interfaceType, type);                           
                            break;
                        case ServiceLifetime.Scoped:
                            builder.Services.TryAddScoped(interfaceType, type);
                            break;
                        case ServiceLifetime.Transient:
                            builder.Services.TryAddTransient(interfaceType, type);
                            break;
                    }
                }

            }
        }
    }
}
